//@ts-check
const {log} = console
var elements = [[],[],[]]

for(var i=0; i<elements.length; i++){
    elements[i].onclick  = function(){
        console.log(i)
    }
}

// elements[2].onclick() //3 i为全局作用域 循环结束i的值为3

// for(var i=0; i<elements.length; i++){
//     elements[i].onclick  = (function(i){
//         return function(){
//             console.log(i)
//         }      
//     })(i)
// }

// elements[2].onclick()

const obj = {
    name: 'Elsa',
    age: 23
}
const obj2 = obj
console.log(obj2)
// ---------------------------------

const arr = [200,300,400]
// const [foo,bar,baz] = arr

// const [, , baz] = arr
const [foo] = arr
// const [, , baz] = arr

console.log(foo)

// ---------------------------------对象解构
log`hello world`

const name = "Tom"
const gender = false
function comStr(str,name,gender){
    log(str)

    return  str[0], name + str[1] + gender + str[2]
}
const result = comStr`${name} is a ${gender}`
log(result)


const error = 'Error: foo'

// function inc(number){
//     return number+1
// }

const inc = (n,m) => {
    //手动return
}

const person ={
    name: 'tom',
    // sayHi: function(){
    //     console.log(`my name is ${this.name}`)
    // }
    sayHi: () => {
        console.log(this)
        console.log(`my name is ${this.name}`)
    },
     sayHiAsync: function(){
         setTimeout(() =>{ //this 为全局对象
             console.log(this)
             console.log(this.name)
         },1000)
     }
    
}

// person.sayHi()
// person.sayHiAsync()

log(Math.random())

const obj1 = {
    name: "tom",
    age: 12,
    sayHi(){
        console.log("sayHi")
    },
    [Math.random()]:"random"
}
log(obj1)

//---------------------

// log(Object.is(+0, -0))
// log(Object.is(NaN ,NaN))

// Object.defineProperty()

const person1 = {
    name: 'Ella',
    age:20
}

const personProxy = new Proxy(person1,{
    get(target,property){
        console.log(target, property)
        // return  property in  target ? target[property]: 'default'
        return Reflect.get(target,property)
    },
    set(target, property, value){
        if(property === 'age'){
            if(!Number.isInteger(value)){
                throw new TypeError(`${value} is not an int`)
            }
        }
        target[property] = value
        console.log(target, property,value)
    },
    has(target,property){
        log('watch logic~~')
        return Reflect.get(target,property)
    },
    deleteProperty(target, property){ //监视到对象的删除操作
        delete target[property]
    }


})

log(Reflect.has(person1,'age'))

//---------------------
// function Person(name){this.name = name}
// Person.prototype.say = function(){
//     log(`hi, my name is ${this.name}`)
// }

class Person {
    constructor(name){
        this.name = name
    }
    sayHello(){
        log( `my name is ${this.name}`)
    }

    static create(name){
        return new Person(name)
    }
}
Person.create('Lily')
log(Person)
class Student extends Person {
    constructor(name, number){
        super(name) //继承父类的构造函数
        this.number = number
    }
    sayHello(){
        super.sayHello()
        log( `my numbet is ${this.number}`)
    }
}

const student = new Student('Elle', '20120903')
// student.sayHello()

//---------------------

const set = new Set(arr)
set.add(1).add(3).add(5)

// log(set)

//---------------------
const map = new Map()
map.set("name", "Jack")
//---------------------Symbol 符号 
const cache = []

//--------------------- a.js
cache['foo'] = 'foo'
//--------------------- b.js
cache['foo'] = '124'
//---------------------
for(const item of arr){
    if(item>200){
        break
    }
}

for(const [key,value] of map){
    // console.log(key,value)
}

// for(const item of obj){
//     console.log(item)
// }

const set1 = new Set(['fpp','bar', 'baz'])

const iterator = set1[Symbol.iterator]()
log(iterator)
log(iterator.next())

const obj3 = { //Iterable
    store: ["foo","bar","baz"],
    [Symbol.iterator]:function(){ //Iterator
        let index = 0
        const self = this
        return {
            next: function(){
                 const result ={ //IterationResult
                    value: self.store[index],
                    done: index >= self.store.length
                }
                index++
                return result;
            }
        }
    }
}

for(let item of obj3){
    console.log(item)
}

//任务清单任务


function * foo1(){ 
    //yield
    console.log('1111')
    yield 100
    console.log('2222')
    yield 200
    console.log('3333')
    yield 300
}

const result1 = foo1()
log(result1.next())
log(result1.next())
log(result1.next())
log(result1.next())

function * createIdMaker(){
    let id = 1
    while(true){ //不会陷入死循环，yield会暂停 
        yield id++
    }
}

const isMaker = createIdMaker()
log(isMaker.next().value)
log(isMaker.next().value)
log(isMaker.next().value)
log(isMaker.next().value)
log(isMaker.next().value)


log(Object.entries(obj))
log(new Map(Object.entries(obj)))
log(map)

const p1 = {
    firstName: 'Li',
    lastName: 'Lei',
    get fullName(){
        return `${this.firstName} ${this.lastName}`
    },
    get sayHello(){
        return `Hello ${this.firstName} ${this.lastName}`
    }
}
log(p1.fullName)
log(p1.sayHello)

// const p2 = Object.assign({}, p1)
// p2.firstName = 'zcx'
// log(p2.fullName)

const descriptors = Object.getOwnPropertyDescriptors(p1)

// const p2 = Object.defineProperties({},descriptors)
// log(p2.fullName)
// p2.firstName = 'zcs'

for(const [name, value] of Object.entries(obj)){
    log(`${name.padEnd(16, '-')}|${value.toString().padStart(3,'0')}`)
}